home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / ODF / OS / FWToolbx / PRAlert.cpp < prev    next >
Encoding:
Text File  |  1996-09-17  |  10.5 KB  |  460 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                PRAlert.cpp
  4. //    Release Version:    $ ODF 2 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWOS.hpp"
  11.  
  12. #ifndef FWODTYPS_H
  13. #include "FWODTyps.h"
  14. #endif
  15.  
  16. #ifndef PRALERT_H
  17. #include "PRAlert.h"
  18. #endif
  19.  
  20. #ifndef FWRESOUR_H
  21. #include "FWResour.h"
  22. #endif
  23.  
  24. #ifndef FWSTRING_H
  25. #include "FWString.h"
  26. #endif
  27.  
  28. #ifndef SOM_Module_OpenDoc_Errors_defined
  29. #include <ErrorDef.xh>
  30. #endif
  31.  
  32. // ----- Macintosh Includes -----
  33.  
  34. #if defined(FW_BUILD_MAC) && !defined(__TEXTUTILS__)
  35. #include <TextUtils.h>
  36. #endif
  37.  
  38. #if defined(FW_BUILD_MAC) && !defined(__ICONS__)
  39. #include <Icons.h>
  40. #endif
  41.  
  42. #if defined(FW_BUILD_MAC) && !defined(__DIALOGS__)
  43. #include <Dialogs.h>
  44. #endif
  45.  
  46. //========================================================================================
  47. //    Runtime Informations
  48. //========================================================================================
  49.  
  50. #ifdef FW_BUILD_MAC    
  51. #pragma segment fwtoolbx
  52. #endif
  53.  
  54. //========================================================================================
  55. // Macintosh Dialog Refcon structure
  56. //========================================================================================
  57.  
  58. #ifdef FW_BUILD_MAC
  59. struct FW_SMacAlertRefCon
  60. {
  61.     short fOkItemID;
  62.     short fCancelItemID;
  63. };
  64.  
  65. #define kDialogID 500
  66. // ----- dialog item ids
  67. #define kButton1ID     1
  68. #define kButton2ID    2
  69. #define kButton3ID     3
  70. #define    kMessageID    4
  71. #define    kIconID        5
  72.  
  73. #endif
  74.  
  75. #ifdef FW_BUILD_MAC    
  76. //========================================================================================
  77. //    MacAlertDialogFilter
  78. //========================================================================================
  79.  
  80. static pascal Boolean MacAlertDialogFilter(DialogPtr theDialog, 
  81.                                             EventRecord * theEvent, 
  82.                                             short *itemHit)
  83. {
  84.     Boolean result = FALSE;
  85.  
  86.     FW_SMacAlertRefCon* alertRefCon = (FW_SMacAlertRefCon*)::GetWRefCon(theDialog);
  87.     
  88.     switch (theEvent->what)
  89.     {
  90.         case keyDown:
  91.         case autoKey:
  92.             {
  93.                 switch (theEvent->message & charCodeMask)
  94.                 {
  95.                     case '.':
  96.                         if (theEvent->modifiers & cmdKey && alertRefCon->fCancelItemID != 0)
  97.                         {
  98.                             result = TRUE;
  99.                             *itemHit = alertRefCon->fCancelItemID;
  100.                         }
  101.                         break;
  102.                     
  103.                     case 0x0D:
  104.                     case 0x03:
  105.                         result = TRUE;
  106.                         *itemHit = alertRefCon->fOkItemID;
  107.                         break;
  108.                     
  109.                     case 0x1B:
  110.                         if (alertRefCon->fCancelItemID != 0)
  111.                         {
  112.                             result = TRUE;
  113.                             *itemHit = alertRefCon->fCancelItemID;
  114.                         }
  115.                         break;                
  116.                 }
  117.                 
  118.                 if (result)        // flash the button
  119.                 {
  120.                     long     theTick;
  121.                     short     itemType;
  122.                     Handle     hItem;
  123.                     Rect    box;
  124.                     
  125.                     ::GetDialogItem(theDialog, *itemHit, &itemType, &hItem, &box);
  126.                     ::HiliteControl((ControlHandle)hItem, 1);
  127.                     ::Delay(6,&theTick);
  128.                     ::HiliteControl((ControlHandle)hItem, 0);            
  129.                 }
  130.             }
  131.             break;
  132.         
  133.         case updateEvt:
  134.             if (theDialog == (DialogPtr)theEvent->message)
  135.             {
  136.                 PenState     ps;
  137.                 Rect        box;
  138.                 Handle        handle;
  139.                 short        type;
  140.                 
  141.                 ::SetPort(theDialog);
  142.                 ::GetPenState(&ps);
  143.                 ::PenSize(3, 3);
  144.                 ::GetDialogItem(theDialog, alertRefCon->fOkItemID, &type, &handle, &box);
  145.                 ::InsetRect(&box, -4, -4);
  146.                 ::FrameRoundRect(&box, 16, 16);
  147.                 ::SetPenState(&ps);
  148.             }
  149.             break;
  150.     }
  151.  
  152.     return result;
  153. }
  154. #endif
  155.  
  156. #ifdef FW_BUILD_MAC
  157. //----------------------------------------------------------------------------------------
  158. //    MacSetButtonText
  159. //----------------------------------------------------------------------------------------
  160.  
  161. static void MacSetButtonText(DialogPtr dialog, short buttonID, Str32 text, FW_Boolean moveButton)
  162. {
  163.     Rect             rect;
  164.     short             type;
  165.     Handle             handle;
  166.  
  167.     ::GetDialogItem(dialog, buttonID, &type, &handle, &rect);
  168.     if (text[0] != 0)
  169.     {
  170.         ::SetControlTitle(ControlHandle(handle), text);
  171.         if (moveButton)
  172.         {
  173.             ::OffsetRect(&rect, 10, 0);
  174.             ::SetDialogItem(dialog, buttonID, type, handle, &rect);
  175.             ::MoveControl(ControlHandle(handle), rect.left, rect.top);
  176.         }
  177.     }
  178.     else
  179.     {
  180.         ::HideControl(ControlHandle(handle));
  181.     }
  182. }
  183. #endif
  184.  
  185. #ifdef FW_BUILD_MAC
  186. //----------------------------------------------------------------------------------------
  187. //    FW_PrivAlert
  188. //----------------------------------------------------------------------------------------
  189. static void MacGetStrings(Environment* ev, Str32 *butString, short index1, short index2, short index3)
  190. {
  191.     FW_CAcquireCFMResourceAccess a(ev);
  192.     if (index1 != 0)
  193.     {
  194.         ::GetIndString(butString[0], kDialogID, index1);
  195.         FW_FailOnError(::ResError());
  196.     }
  197.     if (index2 != 0)
  198.     {
  199.         ::GetIndString(butString[1], kDialogID, index2);
  200.         FW_FailOnError(::ResError());
  201.     }
  202.     if (index3 != 0)
  203.     {
  204.         ::GetIndString(butString[2], kDialogID, index3);
  205.         FW_FailOnError(::ResError());
  206.     }
  207. }
  208.  
  209. #endif
  210.  
  211. //----------------------------------------------------------------------------------------
  212. //    FW_PrivAlert
  213. //----------------------------------------------------------------------------------------
  214. FW_AlertResult SL_API FW_PrivAlert(Environment* ev,
  215.                             FW_HString captionRep,
  216.                             FW_HString messageRep,
  217.                             FW_ButtonType buttonType,
  218.                             FW_IconType iconType,
  219.                             FW_DefaultButton defaultButton,
  220.                             FW_Boolean beep)
  221. {
  222.     FW_CString caption(captionRep);
  223.     FW_CString message(messageRep);
  224.  
  225. #ifdef FW_BUILD_WIN
  226.     UINT dialogFlags = buttonType | iconType | defaultButton | MB_TASKMODAL;
  227.     dialogFlags ^= dialogFlags & MB_SYSTEMMODAL;
  228.     
  229.     // ::MessageBox() doesn't work if mouse capturing is active,
  230.     //  so we release the capture (if any) and then restore it
  231.  
  232.     const HWND hwndCapture = ::GetCapture();
  233.  
  234.     if (hwndCapture != NULL)
  235.         ::ReleaseCapture();
  236.     
  237.     if (beep)
  238.         ::MessageBeep((UINT)iconType);
  239.     
  240.     FW_CAcquireNulTerminatedString255 szMessage(message);
  241.     FW_CAcquireNulTerminatedString255 szCaption(caption);
  242.  
  243.     short result = ::MessageBox(NULL, szMessage, szCaption, dialogFlags);
  244.  
  245.     // Set mouse capture to the window that had it
  246.     if (hwndCapture != 0)
  247.         ::SetCapture(hwndCapture);
  248.  
  249.     return result;
  250. #endif
  251.  
  252. #ifdef FW_BUILD_MAC
  253.  
  254.     GrafPtr curPort;
  255.     ::GetPort(&curPort);
  256.     
  257.     DialogPtr dlg = NULL;
  258.     FW_VOLATILE(dlg);
  259.     
  260.     short items[3];
  261.     short item;
  262.  
  263.     FW_TRY 
  264.     {
  265.         // ----- Open create the dialog (can't do exception here because used to display exception messages)
  266.         {
  267.             FW_CAcquireCFMResourceAccess a(ev);
  268.             dlg = ::GetNewDialog(kDialogID, NULL, WindowPtr(-1));
  269.             FW_FailOnError(::ResError());
  270.         }
  271.         
  272.         FW_SMacAlertRefCon    alertRefCon;
  273.         ::SetWRefCon(dlg, (long)&alertRefCon);
  274.         
  275.         Rect             rect;
  276.         short             type;
  277.         Handle             handle;
  278.         
  279.         ::GetDialogItem(dlg, kMessageID, &type, &handle, &rect);
  280.         
  281.         Str255 str;
  282.         message.ExportPascal(str);
  283.         ::SetDialogItemText(handle, str);
  284.     
  285.         Str32 butString[3];
  286.         butString[0][0] = 0;
  287.         butString[1][0] = 0;
  288.         butString[2][0] = 0;
  289.     
  290.         FW_Boolean moveButton = FALSE;
  291.         
  292.         switch (buttonType)
  293.         {
  294.             case FW_kOK:
  295.                 {
  296.                     MacGetStrings(ev, butString, 1, 0, 0);
  297.                     alertRefCon.fOkItemID = 1;
  298.                     alertRefCon.fCancelItemID = 0;
  299.                     items[0] = FW_kOKButtonPressed;
  300.                     break;
  301.                 }
  302.             case FW_kOKCancel:
  303.                 {
  304.                     MacGetStrings(ev, butString, 1, 2, 0);
  305.                     if (defaultButton == FW_kDefaultButton2)
  306.                     {
  307.                         alertRefCon.fCancelItemID = 0;
  308.                         alertRefCon.fOkItemID = 2;
  309.                     }
  310.                     else
  311.                     {
  312.                         alertRefCon.fOkItemID = 1;
  313.                         alertRefCon.fCancelItemID = 2;
  314.                     }
  315.                     items[0] = FW_kOKButtonPressed;
  316.                     items[1] = FW_kCancelButtonPressed;
  317.                     break;
  318.                 }
  319.             case FW_kAbortRetryIgnore:
  320.                 {
  321.                     MacGetStrings(ev, butString, 3, 4, 5);
  322.                     alertRefCon.fOkItemID = defaultButton + 1;
  323.                     alertRefCon.fCancelItemID = 0;
  324.                     items[0] = FW_kAbortButtonPressed;
  325.                     items[1] = FW_kRetryButtonPressed;
  326.                     items[2] = FW_kIgnoreButtonPressed;
  327.                     break;
  328.                 }
  329.             case FW_kYesNoCancel:
  330.                 {
  331.                     MacGetStrings(ev, butString, 6, 7, 2);
  332.                     if (defaultButton == FW_kDefaultButton1)
  333.                     {
  334.                         alertRefCon.fOkItemID = 1;
  335.                         alertRefCon.fCancelItemID = 3;
  336.                     }
  337.                     else if (defaultButton == FW_kDefaultButton2)
  338.                     {
  339.                         alertRefCon.fOkItemID = 2;
  340.                         alertRefCon.fCancelItemID = 3;
  341.                     }
  342.                     else
  343.                     {
  344.                         // I can't decide if Esc means Yes or No
  345.                         alertRefCon.fOkItemID = 3;
  346.                         alertRefCon.fCancelItemID = 0;
  347.                     }
  348.                     items[0] = FW_kYesButtonPressed;
  349.                     items[1] = FW_kNoButtonPressed;
  350.                     items[2] = FW_kCancelButtonPressed;
  351.                     moveButton = TRUE;
  352.                     break;
  353.                 }
  354.             case FW_kYesNo:
  355.                 {
  356.                     MacGetStrings(ev, butString, 6, 7, 0);
  357.                     alertRefCon.fCancelItemID = 0;
  358.                     if (defaultButton == FW_kDefaultButton2)
  359.                         alertRefCon.fOkItemID = 2;
  360.                     else
  361.                         alertRefCon.fOkItemID = 1;
  362.                     items[0] = FW_kYesButtonPressed;
  363.                     items[1] = FW_kNoButtonPressed;
  364.                     break;
  365.                 }
  366.             case FW_kRetryCancel:
  367.                 {
  368.                     MacGetStrings(ev, butString, 4, 2, 0);
  369.                     if (defaultButton == FW_kDefaultButton2)
  370.                     {
  371.                         alertRefCon.fCancelItemID = 0;
  372.                         alertRefCon.fOkItemID = 2;
  373.                     }
  374.                     else
  375.                     {
  376.                         alertRefCon.fOkItemID = 1;
  377.                         alertRefCon.fCancelItemID = 2;
  378.                     }
  379.                     items[0] = FW_kRetryButtonPressed;
  380.                     items[1] = FW_kCancelButtonPressed;
  381.                     break;
  382.                 }
  383.             default:
  384.                 FW_ASSERT(0);                            // unknown dialogFlags
  385.                 break;
  386.         }
  387.     
  388.         MacSetButtonText(dlg, kButton1ID, butString[0], FALSE);
  389.         MacSetButtonText(dlg, kButton2ID, butString[1], moveButton);
  390.         MacSetButtonText(dlg, kButton3ID, butString[2], FALSE);
  391.             
  392.         // ----- Icons
  393.         Handle hIcon = NULL;
  394.         switch (iconType)
  395.         {
  396.             case FW_kStopAlert:
  397.                 hIcon = ::GetIcon(stopIcon);
  398.                 break;
  399.             
  400.             case FW_kCautionAlert:
  401.                 hIcon = ::GetIcon(cautionIcon);
  402.                 break;
  403.             
  404.             case FW_kNoteAlert:
  405.                 hIcon = ::GetIcon(noteIcon);
  406.                 break;
  407.         };
  408.         
  409.         ::GetDialogItem(dlg, kIconID, &type, &handle, &rect);
  410.         if (hIcon)
  411.         {
  412.             ::SetDialogItem(dlg, kIconID, type, hIcon, &rect);
  413.         }
  414.         else
  415.         {
  416.             ::GetDialogItem(dlg, kIconID, &type, &handle, &rect);
  417.             short left = rect.left;
  418.             ::OffsetRect(&rect, 1000, 0);
  419.             ::SetDialogItem(dlg, kIconID, type, hIcon, &rect);
  420.             
  421.             ::GetDialogItem(dlg, kMessageID, &type, &handle, &rect);
  422.             rect.left = left;
  423.             ::SetDialogItem(dlg, kMessageID, type, handle, &rect);        
  424.         }
  425.             
  426.         if (beep)
  427.             ::SysBeep(16);
  428.     
  429.         ::ShowWindow(dlg);
  430.         
  431.         // ----- Nothing can fail from here on -----
  432.         ModalFilterUPP filterProc = NewModalFilterProc(&MacAlertDialogFilter);
  433.         do
  434.         {
  435.             ::ModalDialog(filterProc, &item);
  436.         } while (item <kButton1ID || item > kButton3ID);
  437.         
  438.         DisposeRoutineDescriptor(filterProc);
  439.         
  440.     }
  441.     FW_CATCH_BEGIN 
  442.     FW_CATCH_REFERENCE(FW_XException, exception)
  443.     {
  444.         FW_SetException(ev, exception);
  445.     }
  446.     FW_CATCH_EVERYTHING () 
  447.     {
  448.         FW_SetEvError(ev, kODErrUndefined);
  449.     }
  450.     FW_CATCH_END
  451.  
  452.     if (dlg)
  453.         ::DisposeDialog(dlg);
  454.     
  455.     ::SetPort(curPort);
  456.     
  457.     return (items[item - 1]);
  458. #endif
  459. }
  460.